package com.cheetah.start.system.admin.controller;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cheetah.start.common.annotation.Log;
import com.cheetah.start.common.annotation.NeedLogin;
import com.cheetah.start.common.base.result.Result;
import com.cheetah.start.common.base.result.ResultController;
import com.cheetah.start.common.config.property.AdminProperty;
import com.cheetah.start.common.constant.SessionConst;
import com.cheetah.start.common.enums.BusinessType;
import com.cheetah.start.common.enums.LoggingType;
import com.cheetah.start.common.listener.OnLineManager;
import com.cheetah.start.system.admin.domain.SysAdmin;
import com.cheetah.start.system.admin.service.SysAdminService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;
import javax.validation.constraints.NotBlank;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Feel
 * @create 2021/7/18
 **/
@Slf4j
@Validated
@RestController
@RequestMapping("/admin")
public class SysAdminController extends ResultController {
    @Autowired
    private SysAdminService sysAdminService;
    @Autowired
    private AdminProperty adminProperty;

    /**
     * 登录
     *
     * @param sysAdmin 系统管理员
     * @return {@link Result}
     */
    @PostMapping("/login")
    @Log(title = "后台登录", describe = "登录", type = BusinessType.QUERY, logType = LoggingType.LOGIN)
    public Result login(@Validated SysAdmin sysAdmin, HttpSession session) {
        QueryWrapper<SysAdmin> wrapper = new QueryWrapper<>();
        wrapper.eq("name", sysAdmin.getName());
        SysAdmin one = sysAdminService.getOne(wrapper);
        if (adminProperty.getLimit() != -1) {
            HashMap<String, Object> limit = (HashMap<String, Object>) session.getAttribute(SessionConst.TIME);
            if (limit != null) {
                Integer limit1 = (Integer) limit.get("limit");
                Date time = (Date) limit.get("time");
                if (limit1 >= adminProperty.getLimit() && DateUtil.between(time, new Date(), DateUnit.SECOND) < adminProperty.getInterval()) {
                    return failure(StrUtil.format("账号或密码输错{}次，请{}秒后再试", adminProperty.getLimit(), adminProperty.getInterval()));
                }
                if (limit1 >= adminProperty.getLimit() && DateUtil.between(time, new Date(), DateUnit.SECOND) > adminProperty.getInterval()) {
                    HashMap<String, Object> limitAndInterval = new HashMap<>();
                    limitAndInterval.put("limit", 0);
                    limitAndInterval.put("time", new Date());
                    session.setAttribute(SessionConst.TIME, limitAndInterval);
                }
            }
        }
        if (one != null) {
            if (one.getPassword().equals(SecureUtil.md5(sysAdmin.getPassword()))) {
                session.setAttribute(SessionConst.NAME, one);
                String sessionId = session.getId();
                log.info("sessionId:[{}]", sessionId);
                return success("登录成功");
            }
        }
        if (adminProperty.getLimit() != -1) {
            HashMap<String, Object> limit = (HashMap<String, Object>) session.getAttribute(SessionConst.TIME);
            HashMap<String, Object> limitAndInterval = new HashMap<>();
            limitAndInterval.put("limit", limit != null ? (Integer) limit.get("limit") + 1 : 1);
            limitAndInterval.put("time", new Date());
            session.setAttribute(SessionConst.TIME, limitAndInterval);
        }
        return failure("账号或密码错误");
    }


    /**
     * 改变
     *
     * @param session 会话
     * @param oldpwd  oldpwd
     * @param newpwd  newpwd
     * @return {@link Result<?>}
     */
    @NeedLogin
    @PostMapping("/change")
    public Result<?> change(@NotBlank(message = "旧密码不能为空") String oldpwd, @NotBlank(message = "新密码不能为空") String newpwd, HttpSession session) {
        SysAdmin admin = (SysAdmin) session.getAttribute(SessionConst.NAME);
        if (SecureUtil.md5(oldpwd).equals(admin.getPassword())) {
            admin.setPassword(SecureUtil.md5(newpwd));
            return decide(sysAdminService.updateById(admin), BusinessType.EDIT);
        }
        return failure("密码错误");
    }

    /**
     * 注销
     *
     * @param session 会话
     * @return {@link Result}
     */
    @GetMapping("/logout")
    public Result logout(HttpSession session) {
        Map<String, HttpSession> sessions = OnLineManager.getInstance().getSessions();
        String id = session.getId();
        sessions.remove(id);
        session.removeAttribute(SessionConst.NAME);
        return success("推出成功");
    }


    /**
     * 信息
     *
     * @param session 会话
     * @return {@link Result}
     */
    @GetMapping("/info")
    public Result info(HttpSession session) {
        SysAdmin admin = (SysAdmin) session.getAttribute(SessionConst.NAME);
        return success(admin);
    }
}
